package relop;

import global.RID;
import global.SearchKey;
import heap.HeapFile;
import index.HashIndex;
import index.HashScan;

/**
 * Wrapper for hash scan, an index access method.
 */
public class KeyScan extends Iterator {

	private HashScan scan;
	private HashIndex index;
	private SearchKey key;
	private HeapFile file;
	private boolean open;
	
	/**
	 * Constructs an index scan, given the hash index and schema.
	 */
	public KeyScan(Schema schema, HashIndex index, SearchKey key, HeapFile file) {
		this.schema = schema;
		this.index = index;
		this.key = new SearchKey(key);
		this.file = file;
		scan = this.index.openScan(this.key);
		open = true;
	}

	/**
	 * Gives a one-line explaination of the iterator, repeats the call on any
	 * child iterators, and increases the indent depth along the way.
	 */
	public void explain(int depth) {
		indent(depth);
		System.out.println("KeyScan of key: " + key.toString() + " on index: "
				+ index.toString() + " and file: " + file.toString());
	}

	/**
	 * Restarts the iterator, i.e. as if it were just constructed.
	 */
	public void restart() {
		if (open) {
			scan.close();
			open = false;
		}

		scan = index.openScan(key);
		open = true;
	}

	/**
	 * Returns true if the iterator is open; false otherwise.
	 */
	public boolean isOpen() {
		return open;
	}

	/**
	 * Closes the iterator, releasing any resources (i.e. pinned pages).
	 */
	public void close() {
		if (open) {
			scan.close();
			scan = null;
			file = null;
			index = null;
			key = null;
			open = false;
		}
	}

	/**
	 * Returns true if there are more tuples, false otherwise.
	 */
	public boolean hasNext() {
		if (open) {
			return scan.hasNext();
		}

		return false;
	}

	/**
	 * Gets the next tuple in the iteration.
	 * 
	 * @throws IllegalStateException
	 *             if no more tuples
	 */
	public Tuple getNext() {
		if (!open) 
			throw new IllegalStateException("getNext() Error: scan closed");
		
		try {
			RID rid = scan.getNext();
			byte[] record = file.selectRecord(rid);

			Tuple tuple = new Tuple(schema, record);

			return tuple;
		} catch (IllegalStateException ex) {
			throw ex;
		}
	}

} // public class KeyScan extends Iterator
